package com.jron.cqiu.kernel.implement;

import com.jron.cqiu.kernel.mail.IMail;
import com.jron.cqiu.kernel.mail.ReceiveType;
import com.jron.cqiu.util.ConfigurationUtil;
import com.jron.cqiu.Constants;
import org.apache.commons.mail.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.lang.StringUtils;

import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.security.Security;
import java.util.Properties;

/**
 * Created by Intellij IDEA.
 *
 * @Author: Yejw
 * @Date: 2008-6-17
 * @Time: 12:44:13
 */
public class Mail implements IMail {

    private static Log log = LogFactory.getLog(Mail.class);

    private String defaultHost = ConfigurationUtil.value("mail.default.host");
    private String defaultCharset = ConfigurationUtil.value("mail.default.charset");
    private String defaultProtocol = ConfigurationUtil.value("mail.default.protocol");
    private String user = ConfigurationUtil.value("mail.user");
    private String password = ConfigurationUtil.value("mail.pwd");
    private String htmlAlternativeMessage = "Your email client does not support HTML messages";

    /**
     * @param mailTo
     * @param mailFrom
     * @param mailSubject
     * @param mailBody
     */
    public void sendHtmlMail(String mailTo, String mailFrom, String mailSubject, String mailBody) {
        sendHtmlMail(mailTo, null, mailFrom, null, mailSubject, mailBody);
    }

    /**
     * @param mailTo
     * @param nameTo
     * @param mailFrom
     * @param nameFrom
     * @param mailSubject
     * @param mailBody
     */
    public void sendHtmlMail(String mailTo, String nameTo, String mailFrom, String nameFrom, String mailSubject,
                             String mailBody) {
        try {
            HtmlEmail email = new HtmlEmail();
            email = (HtmlEmail) emailSet(email, mailTo, nameTo, mailFrom, nameFrom, mailSubject);
            // set the html message
            email.setHtmlMsg(mailBody);
            // set the alternative message
            email.setTextMsg(htmlAlternativeMessage);
            email.send();
        } catch (Exception e) {
            e.printStackTrace();
            log.debug(e.getMessage());
        }
    }

    public void sendHtmlMail(String mailTo, String nameTo, String mailFrom, String nameFrom, String mailSubject,
                             String mailBody, HtmlEmail htmlEmail) {
        try {
            HtmlEmail email = (HtmlEmail) emailSet(htmlEmail, mailTo, nameTo, mailFrom, nameFrom, mailSubject);
            email.setHtmlMsg(mailBody);
            email.setTextMsg(htmlAlternativeMessage);
            email.send();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Email emailSet(Email email, String mailTo, String nameTo, String mailFrom, String nameFrom,
                           String mailSubject) throws EmailException {
        email.setHostName(defaultHost);
        email.setCharset(defaultCharset);
        email.setAuthentication(user, password);
        email.addTo(mailTo, nameTo);
        email.setFrom(mailFrom, nameFrom);
        email.setSubject(mailSubject);
        return email;
    }

    /**
     * @param mailTo
     * @param mailFrom
     * @param mailSubject
     * @param mailBody
     * @param attachment
     */
    public void sendAttachmentMail(String mailTo, String mailFrom, String mailSubject, String mailBody,
                                   EmailAttachment attachment) {
        sendAttachmentMail(mailTo, null, mailFrom, null, mailSubject, mailBody, attachment);
    }

    /**
     * @param mailTo
     * @param nameTo
     * @param mailFrom
     * @param nameFrom
     * @param mailSubject
     * @param mailBody
     * @param attachment
     */
    public void sendAttachmentMail(String mailTo, String nameTo, String mailFrom, String nameFrom, String mailSubject,
                                   String mailBody, EmailAttachment... attachment) {
        try {
            MultiPartEmail email = new MultiPartEmail();
            email = (MultiPartEmail) emailSet(email, mailTo, nameTo, mailFrom, nameFrom, mailSubject);

            email.setMsg(mailBody);
            // add the attachment
            for (EmailAttachment emailAttachment : attachment) email.attach(emailAttachment);
            // send the email
            email.send();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param mailTo
     * @param mailFrom
     * @param mailSubject
     * @param mailBody
     */
    public void sendSimpleMail(String mailTo, String mailFrom, String mailSubject, String mailBody) {
        sendSimpleMail(mailTo, null, mailFrom, null, mailSubject, mailBody);
    }

    /**
     * @param mailTo
     * @param nameTo
     * @param mailFrom
     * @param nameFrom
     * @param mailSubject
     * @param mailBody
     */
    public void sendSimpleMail(String mailTo, String nameTo, String mailFrom, String nameFrom, String mailSubject,
                               String mailBody) {
        try {
            SimpleEmail email = new SimpleEmail();
            email = (SimpleEmail) emailSet(email, mailTo, nameTo, mailFrom, nameFrom, mailSubject);
            email.setMsg(mailBody);
            email.send();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param mailHost
     * @param user
     * @param password
     * @param protocol
     * @return
     */
    public Message[] receiveMail(String mailReceiveHost, String user, String password, String protocol) {
        Session session = null;
        Store store = null;
        Folder folder = null;

        try {
            //gmail
            if (StringUtils.contains(mailReceiveHost, "gmail")) {
                Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
                final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";

                Properties props = System.getProperties();
                props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
                props.setProperty("mail.pop3.socketFactory.fallback", "false");
                props.setProperty("mail.pop3.port", "995");
                props.setProperty("mail.pop3.socketFactory.port", "995");

                session = Session.getDefaultInstance(props, null);
                URLName urln = new URLName(defaultProtocol, "pop.gmail.com", 995, null, user, password);
                store = session.getStore(urln);
                store.connect();
            } else {
                Properties props = new Properties();
                session = Session.getDefaultInstance(props, null);
                store = session.getStore(defaultProtocol);
                store.connect(mailReceiveHost, user, password);
            }
            folder = store.getFolder("INBOX");
            folder.open(Folder.READ_ONLY);
            return folder.getMessages();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param mailHost
     * @param user
     * @param password
     * @return
     */
    public Message[] receiveMail(String mailReceiveHost, String user, String password) {
        return receiveMail(mailReceiveHost, user, password, defaultProtocol);
    }

    /**
     * @param mails
     */
    public void readMail(Message... mails) {
        readMail(null, mails);
    }

    @SuppressWarnings({"ConstantConditions"})
    public void readMail(String attachmentSaveto, Message... mails) {
        PraseMimeMessage pmm = null;
        try {
            for (int i = 0; i < mails.length; i++) {
                pmm = new PraseMimeMessage((MimeMessage) mails[i]);
                log.debug("Message " + i + " subject: " + pmm.getSubject());
                log.debug("Message " + i + " isNew: " + pmm.isNew());
                log.debug("Message " + i + " sentdate: " + pmm.getSentDate());
                log.debug("Message " + i + " replysign: " + pmm.getReplySign());
                log.debug("Message " + i + " hasRead: " + pmm.isNew());
                log.debug("Message " + i + "  containAttachment: " + pmm.isContainAttach(mails[i]));
                log.debug("Message " + i + " form: " + pmm.getFrom());
                log.debug("Message " + i + " to: " + pmm.getMailAddress(ReceiveType.TO));
                log.debug("Message " + i + " cc: " + pmm.getMailAddress(ReceiveType.CC));
                log.debug("Message " + i + " bcc: " + pmm.getMailAddress(ReceiveType.BCC));
                pmm.setDateFormat(Constants.DEFAULT_DATE_FORMAT);
                log.debug("Message " + i + " sentdate: " + pmm.getSentDate());
                log.debug("Message " + i + " Message-ID: " + pmm.getMessageId());
                pmm.getMailContent(mails[i]);
                log.debug("Message " + i + " bodycontent:  " + pmm.getBodyText());
                pmm.setAttachPath(attachmentSaveto);
                pmm.saveAttachMent(mails[i]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
